package cn.itcast.web.shiro;

import cn.itcast.common.utils.HttpUtils;
import cn.itcast.domain.system.Module;
import cn.itcast.domain.system.User;
import cn.itcast.service.system.ModuleService;
import cn.itcast.service.system.UserService;
import cn.itcast.web.token.FaceToken;
import cn.itcast.web.token.WxToken;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 自定义realm域
 *  1、继承父类 AuthorizingRealm
 *  2、实现2个抽象方法（认证，授权）
 */
public class AuthRealm extends AuthorizingRealm {

	@Autowired
	private UserService userService;

	@Autowired
	private ModuleService moduleService;

	/**
	 * 授权方法：
	 *  本质：提供当前登录用户的权限数组（权限名称集合）
	 *  参数：PrincipalCollection（安全数据集合），只获取唯一的一个安全数据（用户对象）
	 *  返回值：
	 *      AuthorizationInfo：授权数据（权限名称集合）
	 *
	 */
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		//1.获取当前登录用户（安全数据）
		User user = (User)principals.getPrimaryPrincipal();
		//2.根据当前登录的用户，查询此用户的模块权限  List<Module>
		List<Module> list = moduleService.findByUser(user);
		//3.提取所有的模块名称:set集合
		Set<String> modulsNames = new HashSet<>();
		for (Module module : list) {
			modulsNames.add(module.getName());
		}
		//4.构造返回值
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		info.setStringPermissions(modulsNames);
		return info;
	}

	/**
	 * 认证: 用户登录
	 *  * 提供数据（提供用户对象），调用service查询数据
	 *  参数：AuthenticationToken （用户登录输入的邮箱和密码）
	 *  返回值：AuthenticationInfo（认证数据）
	 *      * 用户对象
	 */
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		User user = null;
		if(token instanceof WxToken){
			WxToken wxToken = (WxToken) token;
			//1.获取code
			String openid = wxToken.getOpenid();

			//3.根据openid获取用户
			user = userService.findByOpenId(openid);

		}else if(token instanceof FaceToken){
			FaceToken faceToken = (FaceToken) token;
			user = userService.findById(faceToken.getId());
		}else if(token instanceof UsernamePasswordToken) {
			//1.获取输入的邮箱密码
			UsernamePasswordToken upToken = (UsernamePasswordToken) token;
			String email = upToken.getUsername();
			String password = new String(upToken.getPassword()); //将char数组转化为string字符串
			//2.根据邮箱查询用户
			user = userService.findByEmail(email);
		}
		if (user != null) {
			//3.如果用户存在，构造返回值AuthenticationInfo
			/**
			 * AuthenticationInfo：认证数据
			 *  1.安全数据（用户对象）
			 *  2.密码：为了方便操作，存入数据库密码
			 *  3.realm域名称：约定俗称（当前类名）
			 */
			return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
		} else {
			//4.如果用户不存在，返回null(抛出异常)
			return null;
		}
	}
	
}
